package classroom;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;

import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListAdapter;
import android.widget.TextView;
import android.widget.Toast;

import com.project.trac.R;

import core.modules.DatabaseConnector;
import core.modules.Institute;
import core.modules.MultipartUtility;

public class FileUpload extends Institute implements OnClickListener {

	/* File Browsing */
	private File root = new File(Environment.getExternalStorageDirectory() + "/");
	
	// store the names of the traversed directory
	private ArrayList<String> pushDirectory = new ArrayList<String>();

	// check if current level is a directory
	private Boolean firstLvl = true;
	
	// store the objects found in a directory
	private Item[] items;
	
	private File theFile;
	
	// the absolute file to be uploaded to the server
	private String absoluteFile;
	
	// the actual file name
	private String fileName;
	
	private final int DIALOG_LOAD_FILE = 1000;

	
	
	
	
	
	// UI Components 
	private ProgressDialog progressDialog;
	private ListAdapter listAdapter;
	
	private EditText et_filePath;
	private TextView tv_content;
	private TextView tv_date_end;
	
	private String forumID;
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.student_upload_to);
		setTitle("Upload to " + getSubjectName());
		forumID = getIntent().getExtras().getString("FORUM_ID");
		
		progressDialog = new ProgressDialog(FileUpload.this);
		
		et_filePath = (EditText) findViewById(R.id.et_filepath);
		tv_content = (TextView) findViewById(R.id.tv_content);
		tv_date_end = (TextView) findViewById(R.id.tv_date_end);
		
		try {
			String item = new AsynchronousTask().execute("initialize").get();
			
			tv_date_end.setText(item.subSequence(0, item.indexOf((char) 234)).toString());
			tv_content.setText(item.subSequence(item.indexOf((char) 234)+1, item.length()).toString());
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		}
		
		findViewById(R.id.btn_browse).setOnClickListener(this);
		findViewById(R.id.btn_upload).setOnClickListener(this);
		
	}
	 
	@Override
	public void onBackPressed() {
		super.onBackPressed();
	}
	
	@SuppressWarnings("deprecation")
	@Override
	public void onClick(View v) {

		switch(v.getId()) {
			case R.id.btn_upload:
			if (theFile.length() <= 3145728L) {
				try {
					progressDialog = ProgressDialog.show(FileUpload.this, null, "Uploading " + fileName , true);

					new Thread(new Runnable() {
						public void run() {
							runOnUiThread(new Runnable() {
								public void run() {
									Toast.makeText(FileUpload.this, "File upload started.", Toast.LENGTH_SHORT).show();
								}
							});
							uploadFile(absoluteFile);
							new AsynchronousTask().execute("upload");
						}
					}).start();
					
				} catch (NullPointerException e) {
					Toast.makeText(FileUpload.this, "No file selected.", Toast.LENGTH_SHORT).show();
				}


			} else {
				Toast.makeText(FileUpload.this, "file is > 3mb", Toast.LENGTH_SHORT).show();
			}
			
				break;
			case R.id.btn_browse:
				loadFileList();
				showDialog(DIALOG_LOAD_FILE);
				break;
			default:
				et_filePath.setText("");
				break;
		}
		
	}
	
	@Override
	protected Dialog onCreateDialog(int id) {
		
		Dialog dialog = null;
		AlertDialog.Builder builder = new Builder(this);

		if (items == null) {
//			Log.e(TAG, "No files loaded");
			Toast.makeText(FileUpload.this, "No file selected.", Toast.LENGTH_SHORT).show();
			dialog = builder.create();
			
			return dialog;
		}

		switch (id) {
		
		case DIALOG_LOAD_FILE:
			builder.setTitle("Select file -");
			builder.setAdapter(listAdapter, new DialogInterface.OnClickListener() {
				@SuppressWarnings("deprecation")
				@Override
				public void onClick(DialogInterface dialog, int which) {
					
					absoluteFile = items[which].file;
					
					File sel = new File(root + "/" + absoluteFile);
					if (sel.isDirectory()) {
						firstLvl = false;

						// Adds chosen directory to list
						pushDirectory.add(absoluteFile);
						items = null;
						root = new File(sel + "");

						loadFileList();
						removeDialog(DIALOG_LOAD_FILE);
						showDialog(DIALOG_LOAD_FILE);
//						Log.d(TAG, root.getAbsolutePath());
					}

					// Checks if 'up' was clicked
					else if (absoluteFile.equalsIgnoreCase("up") && !sel.exists()) {

						// present directory removed from list
						String s = pushDirectory.remove(pushDirectory.size() - 1);

						// path modified to exclude present directory
						root = new File(root.toString().substring(0,root.toString().lastIndexOf(s)));
						items = null;

						// if there are no more directories in the list, then
						// its the first level
						if (pushDirectory.isEmpty()) {
							firstLvl = true;
						}
						loadFileList();

						removeDialog(DIALOG_LOAD_FILE);
						showDialog(DIALOG_LOAD_FILE);
						//Log.d(TAG, root.getAbsolutePath());

					}
					// File picked
					else {
						fileName = absoluteFile;
						absoluteFile = root.getAbsolutePath().concat("/" + absoluteFile);
						et_filePath.setText(absoluteFile);
						theFile = new File(absoluteFile);
						//Log.i("ELSE - CURRENT DIR", root.getAbsolutePath());
						//Log.i("The Chosen File", chosenFile);
						//Log.i("filePath.getText", filePath.getText().toString());
						//Toast.makeText(UploadForm.this, chosenFile, Toast.LENGTH_SHORT).show();
					}

				}
			});
			break;
		}
		dialog = builder.show();
		return dialog;
	}

	private void uploadFile(String targetFile) {
		
		try {
			File file = new File(targetFile);
			
            MultipartUtility multipart = new MultipartUtility(DatabaseConnector.getWebUploader(), "UTF-8");
            multipart.addFormField("catalogName", getSubjectName());
            multipart.addFilePart("uploaded_file", file);
            
            
            List<String> response = multipart.finish();
             
            for (String line : response) {
                if (line.equalsIgnoreCase("Success!")) {
            		progressDialog.dismiss();
            		runOnUiThread(new Runnable() {
						public void run() {
							Toast.makeText(getApplicationContext(), "upload complete", Toast.LENGTH_SHORT).show();
						}
					});
                }
            }
            
        } catch (IOException e) {
           DatabaseConnector.Logger(getClass(), "uploadFile", e);
        }
		
	}
	
	private void loadFileList() {
		
		try {
			root.mkdirs();
		} catch (SecurityException e) {
//			Log.e(TAG, "unable to write on the sd card ");
			Toast.makeText(FileUpload.this, "Unable to write on the SD card.", Toast.LENGTH_SHORT).show();
		}

		// Checks whether path exists
		if (root.exists()) {
			FilenameFilter filter = new FilenameFilter() {
				@Override
				public boolean accept(File dir, String filename) {
					File sel = new File(dir, filename);
					// Filters based on whether the file is hidden or not
					return (sel.isFile() || sel.isDirectory())
							&& !sel.isHidden();

				}
			};

			String[] fList = root.list(filter);
			items = new Item[fList.length];
			for (int i = 0; i < fList.length; i++) {
				items[i] = new Item(fList[i], R.drawable.browser_file);

				// Convert into file path
				File sel = new File(root, fList[i]);

				// Set drawables
					if (sel.isDirectory()) {
						items[i].icon = R.drawable.browser_directory;
						//Log.d("DIRECTORY", items[i].file);
					} else {
						//Log.d("FILE", items[i].file);
					} 
			}

			if (!firstLvl) {
				Item temp[] = new Item[items.length + 1];
				for (int i = 0; i < items.length; i++) {
					temp[i + 1] = items[i];
				}
				temp[0] = new Item("Up", R.drawable.browser_up);
				items = temp;
			}
		} else {
//			Log.e(TAG, "path does not exist");
			Toast.makeText(FileUpload.this, "Invalid file path.", Toast.LENGTH_SHORT).show();
		}

		listAdapter = new ArrayAdapter<Item>(this,android.R.layout.select_dialog_item, android.R.id.text1, items) {
			@Override
			public View getView(int position, View convertView, ViewGroup parent) {
				// creates view
				View view = super.getView(position, convertView, parent);
				TextView textView = (TextView) view.findViewById(android.R.id.text1);

				// put the image on the text view
				textView.setCompoundDrawablesWithIntrinsicBounds(items[position].icon, 0, 0, 0);

				// add margin between image and text (support various screen
				// densities)
				int dp5 = (int) (5 * getResources().getDisplayMetrics().density + 0.5f);
				textView.setCompoundDrawablePadding(dp5);

				return view;
			}
		};

	}
	
	private class Item {
		
		private String file;
		private int icon;

		public Item(String file, Integer icon) {
			this.file = file;
			this.icon = icon;
		}

		@Override
		public String toString() {
			return file;
		}
	}

	private class AsynchronousTask extends AsyncTask<String, String, String> {
		
		protected void onPreExecute() {
			super.onPreExecute();
		}

		protected String doInBackground(String... args) {
			try {
				
				if (args[0].equalsIgnoreCase("initialize")) {
					final ResultSet rs = DatabaseConnector.getStatement().executeQuery(
							"SELECT title, content, DATE_FORMAT(date_end,'%Y-%b-%d') AS 'end' "
							+ " FROM forum WHERE sid = " + getSubjectID() + " AND id = " + forumID);
					

					while (rs.next()) {
						return  rs.getString("end") + (char) 234 + rs.getString("content");
					}
				}
				
				if (args[0].equalsIgnoreCase("upload")) {
					DatabaseConnector.setPreparedStatement("INSERT INTO documents (cid, uid, name, header) VALUES (?,?,?,?)");
					PreparedStatement pps = DatabaseConnector.getPreparedStatement();
					pps.setInt(1, getSubjectID());
					pps.setInt(2, getUserID());
					pps.setString(3, fileName);
					pps.setString(4, getSubjectName());

					pps.executeUpdate();
					pps.close();
				}

		} catch (SQLException e) {
			DatabaseConnector.Logger(getClass(), "doInBackground", e);
		} 

			return null;
		}

		protected void onPostExecute(String postExecute) { 
		}
	}


}